package com.kool.system.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kool.core.CoreConstants;
import com.kool.core.cache.KCache;
import com.kool.core.exception.AppException;
import com.kool.core.util.StringUtils;
import com.kool.system.bean.SyAutDefBean;
import com.kool.system.bean.SyRoleAutBean;
import com.kool.system.bean.SyRoleBean;
import com.kool.system.bean.SyRoleGroupBean;
import com.kool.system.bean.SyRoleRoleGroupBean;
import com.kool.system.bean.SyUserAutBean;
import com.kool.system.bean.SyUserInfoBean;
import com.kool.system.bean.SyUserRoleBean;
import com.kool.system.bean.io.SYPAGEINFOYBean;
import com.kool.system.bean.vo.PageResult;
import com.kool.system.dao.SyRoleAutDao;
import com.kool.system.dao.SyRoleDao;
import com.kool.system.dao.SyRoleRoleGroupDao;
import com.kool.system.dao.SyUserRoleDao;
import com.kool.system.util.CommonUtils;

@Service
public class RoleService {
	private static Logger logger = Logger.getLogger(RoleService.class);
	@Autowired
	private SyRoleDao syRoleDao;

	@Autowired
	private SyRoleRoleGroupDao syRoleRoleGroupDao;

	@Autowired
	private SyUserRoleDao syUserRoleDao;

	@Autowired
	private SyRoleAutDao syRoleAutDao;

	@Autowired
	private UserService userService;

	/**
	 * @DESCRIBE 增加
	 */
	public void add(SyRoleBean syRole) throws AppException {
		if (null == syRole) {
			throw new AppException("SY000027");// 输入信息为空
		}
		SyRoleBean role = syRoleDao.selectByPK(syRole);
		if (role != null) {
			throw new AppException("SY000045");// 角色码已经存在
		}
		logger.debug(syRole.toString());
		syRoleDao.insert(syRole);
		
		//刷新缓存
		KCache.refresh(CoreConstants.KCACHE_ROLE);
	}

	/**
	 * @DESCRIBE 修改
	 */
	public void update(SyRoleBean syRole) throws AppException {
		if (null == syRole) {
			throw new AppException("SY000027");// 输入信息为空
		}
		logger.debug(syRole.toString());
		syRoleDao.update(syRole);
		
		//刷新缓存
		KCache.refresh(CoreConstants.KCACHE_ROLE);
	}

	/**
	 * @DESCRIBE 删除
	 */
	public void delete(SyRoleBean syRole) throws AppException {
		if (null == syRole) {
			throw new AppException("SY000027");// 输入信息为空
		}
		String roleCode = syRole.getSroRoleCode();
		// 如果有关联用户不允许删除
		SyUserRoleBean userRole = new SyUserRoleBean();
		userRole.setSurRoleCode(roleCode);
		int total = syUserRoleDao.selectTotal(userRole);
		if (total > 0) {
			throw new AppException("SY000050");// 角色有关联用户，无法删除
		}

		// 删除角色角色组关联
		SyRoleRoleGroupBean rrgInfo = new SyRoleRoleGroupBean();
		rrgInfo.setSrrRoleCode(roleCode);
		syRoleRoleGroupDao.deletes(rrgInfo);
		// 删除角色权限关联
		SyRoleAutBean roleAut = new SyRoleAutBean();
		roleAut.setSraRoleCode(roleCode);
		syRoleAutDao.deletes(roleAut);

		logger.debug(syRole.toString());
		syRoleDao.delete(syRole);
		
		//刷新缓存
		KCache.refresh(CoreConstants.KCACHE_ROLE);
	}

	/**
	 * @DESCRIBE 分页查询
	 */
	public PageResult queryPage(SyRoleBean syRole, SYPAGEINFOYBean pageInfo) {
		int total = syRoleDao.selectTotal(syRole);

		int currentPage = pageInfo.getCurrentPage();
		int pageSize = pageInfo.getPageSize();
		int offset = (currentPage - 1) * pageSize;
		int pageCount = (total + pageSize - 1) / pageSize;
		List<SyRoleBean> list = syRoleDao.selectPage(syRole, offset, pageInfo.getPageSize());

		pageInfo.setTotal(total);
		pageInfo.setPageCount(pageCount);

		PageResult pageResult = new PageResult();
		pageResult.setListBusinessValue(new ArrayList<>(list));
		pageResult.setPageInfo(pageInfo);
		return pageResult;
	}

	/**
	 * @DESCRIBE 查询
	 */
	public List<SyRoleBean> query(SyRoleBean syRole) throws AppException {
		if (null == syRole) {
			syRole = new SyRoleBean();
		}

		logger.debug(syRole.toString());
		return syRoleDao.select(syRole);
	}

	/**
	 * 
	 * @DESCRIBE 根据主键查询一条记录
	 * @DATE 2018年7月11日 下午7:04:20
	 *
	 * @param pk
	 * @return
	 * @throws AppException
	 */
	public SyRoleBean queryOne(SyRoleBean pk) throws AppException {
		if (null == pk) {
			throw new AppException("SY000028");// 输入主键为空
		}

		logger.debug(pk.toString());
		return syRoleDao.selectByPK(pk);
	}

	/**
	 * @DESCRIBE 查询角色所属角色组列表
	 * @DATE 2018年7月11日 下午7:09:46
	 *
	 * @param roleCode
	 * @return
	 */
	public List<SyRoleGroupBean> queryGroupsOfRole(String roleCode) {
		List<SyRoleGroupBean> listGroups = new ArrayList<>();
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT B.* FROM SY_ROLE_ROLE_GROUP A,SY_ROLE_GROUP B ");
		sb.append("WHERE A.SRR_GROUP_CODE=B.SRG_GROUP_CODE ");
		sb.append("AND A.SRR_ROLE_CODE = \"" + roleCode + "\"");
		logger.debug(sb.toString());
		List<Map<String, Object>> list = syRoleRoleGroupDao.selectBySql(sb.toString());
		if (list != null) {
			for (Map<String, Object> map : list) {
				SyRoleGroupBean group = SyRoleGroupBean.DBResultToBean(map);
				listGroups.add(group);
			}
		}

		return listGroups;
	}

	/**
	 * 
	 * @DESCRIBE 查询角色关联用户列表
	 * @DATE 2018年7月11日 下午7:19:52
	 *
	 * @param roleCode
	 * @return
	 */
	public List<SyUserInfoBean> queryUsersOfRole(String roleCode) {
		List<SyUserInfoBean> listUsers = new ArrayList<>();
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT B.* FROM SY_USER_ROLE A, SY_USER_INFO B ");
		sb.append("WHERE A.SUR_USER_CID=B.SUI_USER_CID ");
		sb.append("AND A.SUR_ROLE_CODE=\"" + roleCode + "\"");
		logger.debug(sb.toString());
		List<Map<String, Object>> list = syUserRoleDao.selectBySql(sb.toString());
		if (list != null) {
			for (Map<String, Object> map : list) {
				SyUserInfoBean user = SyUserInfoBean.DBResultToBean(map);
				listUsers.add(user);
			}
		}
		return listUsers;
	}

	/**
	 * @DESCRIBE 查询角色所属角色组列表
	 * @DATE 2018年7月11日 下午9:38:00
	 *
	 * @param roleCode
	 * @return
	 * @throws AppException
	 */
	public List<SyRoleRoleGroupBean> queryGroupOfRole(String roleCode) throws AppException {
		if (StringUtils.isEmpty(roleCode)) {
			throw new AppException("SY000029");// 角色编码为空
		}
		SyRoleRoleGroupBean info = new SyRoleRoleGroupBean();
		info.setSrrRoleCode(roleCode);
		logger.debug(info.toString());
		List<SyRoleRoleGroupBean> list = syRoleRoleGroupDao.select(info);
		return list;
	}

	/**
	 * @DESCRIBE 加入角色组
	 * @DATE 2018年7月11日 下午9:03:40
	 *
	 * @param roleCode
	 * @param listIn
	 * @throws AppException
	 */
	public void joinGroup(String roleCode, List<SyRoleRoleGroupBean> listIn) throws AppException {
		if (StringUtils.isEmpty(roleCode)) {
			throw new AppException("SY000029");// 角色编码为空
		}
		SyRoleRoleGroupBean info = new SyRoleRoleGroupBean();
		info.setSrrRoleCode(roleCode);
		logger.debug(info.toString());
		syRoleRoleGroupDao.deletes(info);

		// 加备注
		SyRoleBean role = (SyRoleBean) KCache.get(CoreConstants.KCACHE_ROLE, roleCode);
		if (listIn != null && listIn.size() > 0) {
			for (SyRoleRoleGroupBean rrg : listIn) {
				SyRoleGroupBean group = (SyRoleGroupBean) KCache.get(CoreConstants.KCACHE_ROLE_GROUP,
						rrg.getSrrGroupCode());
				rrg.setSrrCmt(new StringBuilder().append(role.getSroName()).append("-").append(group.getSrgName())
						.toString());
			}
			syRoleRoleGroupDao.insertBatch(listIn);
		}

		// 获得角色组权限
		// 查询角色关联角色组权限与角色权限的并集
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT \"");
		sb.append(roleCode);
		sb.append("\" ");
		sb.append("roleCode,B.SGA_AUT_CODE autCode FROM SY_ROLE_ROLE_GROUP A, SY_ROLE_GROUP_AUT B ");
		sb.append("WHERE A.SRR_GROUP_CODE=B.SGA_GROUP_CODE ");
		sb.append("AND A.SRR_ROLE_CODE=\"");
		sb.append(roleCode);
		sb.append("\"");
		sb.append("UNION ");
		sb.append("SELECT \"");
		sb.append(roleCode);
		sb.append("\" ");
		sb.append("roleCode,C.SRA_AUT_CODE autCode FROM SY_ROLE_AUT C ");
		sb.append("WHERE C.SRA_ROLE_CODE=\"");
		sb.append(roleCode);
		sb.append("\"");
		logger.debug(sb.toString());
		List<Map<String, Object>> listRet = syRoleRoleGroupDao.selectBySql(sb.toString());
		List<SyRoleAutBean> listRoleAut = new ArrayList<>();
		if (listRet != null && listRet.size() > 0) {
			for (Map<String, Object> mapRet : listRet) {
				SyRoleAutBean roleAut = new SyRoleAutBean();
				roleAut.setSraRoleCode((String) mapRet.get("roleCode"));
				roleAut.setSraAutCode((String) mapRet.get("autCode"));
				listRoleAut.add(roleAut);
			}
			resetAuth(roleCode, listRoleAut);
		}
	}

	/**
	 * @DESCRIBE 查询角色权限
	 * @DATE 2018年7月11日 下午9:15:33
	 *
	 * @param roleCode
	 * @return
	 * @throws AppException
	 */
	public List<SyRoleAutBean> queryRoleAuth(String roleCode) throws AppException {
		if (StringUtils.isEmpty(roleCode)) {
			throw new AppException("SY000029");// 角色编码为空
		}
		SyRoleAutBean info = new SyRoleAutBean();
		info.setSraRoleCode(roleCode);
		logger.debug(info.toString());
		List<SyRoleAutBean> list = syRoleAutDao.select(info);
		return list;
	}

	/**
	 * @DESCRIBE 角色授权，同时会增量授权用户权限
	 * @DATE 2018年7月11日 下午9:25:22
	 *
	 * @param roleCode
	 * @param listIn
	 * @throws AppException
	 */
	public void resetAuth(String roleCode, List<SyRoleAutBean> listIn) throws AppException {
		if (StringUtils.isEmpty(roleCode)) {
			throw new AppException("SY000029");// 角色编码为空
		}
		SyRoleAutBean info = new SyRoleAutBean();
		info.setSraRoleCode(roleCode);
		logger.debug(info.toString());
		syRoleAutDao.deletes(info);

		// 加备注
		SyRoleBean role = (SyRoleBean) KCache.get(CoreConstants.KCACHE_ROLE, roleCode);
		if (listIn != null && listIn.size() > 0) {
			for (SyRoleAutBean roleAut : listIn) {
				SyAutDefBean aut = (SyAutDefBean) KCache.get(CoreConstants.KCACHE_AUT, roleAut.getSraAutCode());
				roleAut.setSraCmt(
						new StringBuilder().append(role.getSroName()).append("-").append(aut.getSadName()).toString());
			}
			syRoleAutDao.insertBatch(listIn);
		}

		// 角色关联用户同时授权
		// 查询角色用户列表
		SyUserRoleBean syUserRole = new SyUserRoleBean();
		syUserRole.setSurRoleCode(roleCode);
		logger.debug(syUserRole.toString());
		List<SyUserRoleBean> listUsers = syUserRoleDao.select(syUserRole);
		if (listUsers != null && listUsers.size() > 0) {
			// 对每个用户重新授权
			for (SyUserRoleBean syUserRoleBean : listUsers) {
				String userCid = syUserRoleBean.getSurUserCid();
				// 查询用户已有权限
				List<SyUserAutBean> listUserAutOld = userService.queryUserAuth(userCid);
				List<SyUserAutBean> listUserAut = new ArrayList<>();
				// 新用户权限取已有权限和角色权限的并集
				listUserAut.addAll(listUserAutOld);
				for (SyRoleAutBean roleAut : listIn) {
					String autCode = roleAut.getSraAutCode();
					if (userAutContainAut(listUserAutOld, autCode)) {
						continue;
					}
					SyUserAutBean userAut = new SyUserAutBean();
					userAut.setSuaUserCid(syUserRoleBean.getSurUserCid());
					userAut.setSuaAutCode(roleAut.getSraAutCode());

					// 验证权限类型和用户类型关系是否匹配
					CommonUtils.validateAutType(userCid, userAut.getSuaAutCode());

					listUserAut.add(userAut);
				}
				userService.resetAuth(userCid, listUserAut);
			}
		}

	}

	/**
	 * @DESCRIBE 判断用户已有权限是否包含新授权的权限
	 * @DATE 2018年7月11日 下午10:18:33
	 *
	 * @param listUserAutOld
	 * @param autCode
	 * @return
	 */
	private boolean userAutContainAut(List<SyUserAutBean> listUserAutOld, String autCode) {
		boolean isContain = false;
		if (null == listUserAutOld || listUserAutOld.size() <= 0) {
			isContain = false;
		}
		for (SyUserAutBean userAut : listUserAutOld) {
			if (userAut.getSuaAutCode().equals(autCode)) {
				isContain = true;
			}
		}
		return isContain;
	}
}
